package utils
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.Graphics;
	import flash.display.MovieClip;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.LocalConnection;
	import flash.system.System;
	import flash.utils.Dictionary;

	public class DisplayUtil
	{
		/**
		 *取得显示对象的可视矩形
		 * @param display 显示对象
		 * @return 
		 * 
		 */		
		public static function getVisibleRect(display:DisplayObject):Rectangle 
		{
			var bitmapDataSize:int = 2000;
			var bounds:Rectangle;
			var bitmapData:BitmapData = new BitmapData(bitmapDataSize, bitmapDataSize, true, 0);
			bitmapData.draw(display);
			bounds = bitmapData.getColorBoundsRect( 0xFF000000, 0x00000000, false );
			bitmapData.dispose();
			bitmapData=null;
			
			var retultRect:Rectangle = new Rectangle(bounds.x, bounds.y, bounds.x + bounds.width, bounds.y + bounds.height);
			bounds=null;
			return retultRect;
		}
		
		/**
		 *清理指定对象资源，无法清理对象的事件，如果对象存在监听事件需事先移除监听事件，可清对向类型：Bitmap、BitmapData、MovieClip、Array、Dictionary以及有dispose方法的对象
		 * @param object
		 * 说明：如果清理对向为Dictionary、Array时，必须保证其中再无下级Dictionary、Array，且其中的对向必须有dispose方法
		 */
		public static function dispose(object:Object):void
		{
			if(!object)return;
			if(object is Bitmap)
			{
				var bm:Bitmap=object as Bitmap;
				if(bm.parent)bm.parent.removeChild(bm);
				if(bm.bitmapData)bm.bitmapData.dispose();
				bm.bitmapData=null;
				bm=null;
			}
			else if(object is BitmapData)
			{
				var bmd:BitmapData=object as BitmapData;
				bmd.dispose();
				bmd=null;
			}
			else if(object is MovieClip)
			{
				if(object.hasOwnProperty("dispose"))object.dispose();
				var mc:MovieClip=object as MovieClip;
				if(mc.parent)mc.parent.removeChild(mc);
				mc=null;
			}
			else if(object is Array)
			{
				var arr:Array=object as Array;
				while(arr.length)
				{
					var o:*=arr.shift();
					o.dispose();//被清理的对向必须有dispose方法，不然会不能清理
					o=null;
				}
				arr=null;
			}
			else if(object is Dictionary)
			{
				var dic:Dictionary=object as Dictionary;
				for each(var obj:* in dic)
				{
					obj.dispose();//被清理的对向必须有dispose方法，不然会不能清理
					obj=null;
				}
				deleteDictionary(dic);
				dic=null;
			}
			else
			{
				if(object.hasOwnProperty("dispose"))object.dispose();
				if(object.hasOwnProperty("parent") && object.parent)object.parent.removeChild(object);
				object=null;
			}
			object=null;
//			GC();
		}
		
		/**
		 *删除Dictionary中的项，此方法不会清空项自身的资源，仅只是删除完Dictionary自已的项
		 * @param dic
		 * 
		 */
		public static function deleteDictionary(dic:Dictionary):void
		{
			for(var obj:Object in dic)
			{
				delete dic[obj];
				obj=null;
			}

			for(obj in dic)
			{
				deleteDictionary(dic);
				break;
			}
		}
		
		/**
		 *使指定的 XML 对象立即可进行垃圾回收 
		 * @param xml 清空对象
		 * 
		 */		
		public static function disposeXML(xml:XML):void
		{
			System.disposeXML(xml);
			xml=null;
		}
		
		public static function GC():void
		{
			var lc1:LocalConnection;
			var lc2:LocalConnection;
			try
			{
				lc1=new LocalConnection();
				lc2=new LocalConnection();
				lc1.connect("gc");
				lc2.connect("gc");
				lc1.close();
				lc2.close();
			}
			catch(e:Error)
			{
				lc1=null;
				lc2=null;
			}
			return;
		}
		
		/**
		 * 画虚线
		 * 
		 * @param    graphics    <b>    Graphics</b> 
		 * @param    beginPoint    <b>    Point    </b> 起始点坐标
		 * @param    endPoint    <b>    Point    </b> 终点坐标
		 * @param    width        <b>    Number    </b> 虚线的长度
		 * @param    grap        <b>    Number    </b> 虚线短线之间的间隔
		 */
		public static function drawDashed(graphics:Graphics, beginPoint:Point, endPoint:Point, width:Number, grap:Number):void
		{
			if (!graphics || !beginPoint || !endPoint || width <= 0 || grap <= 0) return;
			
			var Ox:Number = beginPoint.x;
			var Oy:Number = beginPoint.y;
			
			var radian:Number = Math.atan2(endPoint.y - Oy, endPoint.x - Ox);
			var totalLen:Number = Point.distance(beginPoint, endPoint);
			var currLen:Number = 0;
			var x:Number, y:Number;
			
			while (currLen <= totalLen)
			{
				x = Ox + Math.cos(radian) * currLen;
				y = Oy +Math.sin(radian) * currLen;
				graphics.moveTo(x, y);
				
				currLen += width;
				if (currLen > totalLen) currLen = totalLen;
				
				x = Ox + Math.cos(radian) * currLen;
				y = Oy +Math.sin(radian) * currLen;
				graphics.lineTo(x, y);
				
				currLen += grap;
			}
		}
	}
}